package cn.edu.tju.elm.repository;

import cn.edu.tju.elm.model.BankCardTransaction;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 银行卡交易记录数据访问层
 */
@Repository
public interface BankCardTransactionRepository extends JpaRepository<BankCardTransaction, Long> {

    /**
     * 根据银行卡ID查找交易记录
     * @param bankCardId 银行卡ID
     * @return 交易记录列表
     */
    List<BankCardTransaction> findByBankCardId(Long bankCardId);

    /**
     * 根据用户ID查找交易记录
     * @param userId 用户ID
     * @return 交易记录列表
     */
    List<BankCardTransaction> findByUserId(Long userId);

    /**
     * 根据用户ID分页查找交易记录
     * @param userId 用户ID
     * @param pageable 分页参数
     * @return 分页交易记录
     */
    Page<BankCardTransaction> findByUserId(Long userId, Pageable pageable);

    /**
     * 根据银行卡ID分页查找交易记录
     * @param bankCardId 银行卡ID
     * @param pageable 分页参数
     * @return 分页交易记录
     */
    Page<BankCardTransaction> findByBankCardId(Long bankCardId, Pageable pageable);

    /**
     * 根据交易流水号查找交易记录
     * @param transactionNo 交易流水号
     * @return 交易记录
     */
    Optional<BankCardTransaction> findByTransactionNo(String transactionNo);

    /**
     * 根据订单ID查找交易记录
     * @param orderId 订单ID
     * @return 交易记录列表
     */
    List<BankCardTransaction> findByOrderId(Long orderId);

    /**
     * 根据交易类型查找交易记录
     * @param userId 用户ID
     * @param transactionType 交易类型
     * @return 交易记录列表
     */
    List<BankCardTransaction> findByUserIdAndTransactionType(Long userId, Integer transactionType);

    /**
     * 根据时间范围查找交易记录
     * @param userId 用户ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 交易记录列表
     */
    @Query("SELECT t FROM BankCardTransaction t WHERE t.user.id = :userId " +
           "AND t.transactionTime >= :startTime AND t.transactionTime <= :endTime " +
           "ORDER BY t.transactionTime DESC")
    List<BankCardTransaction> findByUserIdAndTimeRange(@Param("userId") Long userId,
                                                       @Param("startTime") LocalDateTime startTime,
                                                       @Param("endTime") LocalDateTime endTime);

    /**
     * 根据时间范围分页查找交易记录
     * @param userId 用户ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param pageable 分页参数
     * @return 分页交易记录
     */
    @Query("SELECT t FROM BankCardTransaction t WHERE t.user.id = :userId " +
           "AND t.transactionTime >= :startTime AND t.transactionTime <= :endTime " +
           "ORDER BY t.transactionTime DESC")
    Page<BankCardTransaction> findByUserIdAndTimeRange(@Param("userId") Long userId,
                                                       @Param("startTime") LocalDateTime startTime,
                                                       @Param("endTime") LocalDateTime endTime,
                                                       Pageable pageable);

    /**
     * 统计用户交易记录数量
     * @param userId 用户ID
     * @return 交易记录数量
     */
    long countByUserId(Long userId);

    /**
     * 统计银行卡交易记录数量
     * @param bankCardId 银行卡ID
     * @return 交易记录数量
     */
    long countByBankCardId(Long bankCardId);

    /**
     * 根据交易状态查找交易记录
     * @param userId 用户ID
     * @param status 交易状态
     * @return 交易记录列表
     */
    List<BankCardTransaction> findByUserIdAndStatus(Long userId, Integer status);

    /**
     * 根据银行卡ID和交易状态查找交易记录
     * @param bankCardId 银行卡ID
     * @param status 交易状态
     * @return 交易记录列表
     */
    List<BankCardTransaction> findByBankCardIdAndStatus(Long bankCardId, Integer status);

    /**
     * 查找最近的交易记录
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 最近的交易记录
     */
    @Query("SELECT t FROM BankCardTransaction t WHERE t.user.id = :userId " +
           "ORDER BY t.transactionTime DESC")
    List<BankCardTransaction> findRecentTransactionsByUserId(@Param("userId") Long userId, Pageable pageable);
}
